#pragma once

#include<string>
#include<stack>
#include<map>
#include<vector>

#include "config.h"

#define ABSTRACT(CLASS) public:virtual ~CLASS()=0{}
#define STATIC(CLASS) ABSTRACT(CLASS) protected:CLASS(){}
#define SINGLETON(CLASS) public:static CLASS* Instance(); ~CLASS(); protected:CLASS(){} private:static CLASS* _instance;
#define SINGLETON_INIT(CLASS) CLASS* CLASS::Instance(){if(_instance==NULL) _instance=new CLASS(); return _instance;} CLASS::~CLASS(){if(_instance!=NULL) delete _instance;} CLASS* CLASS::_instance=NULL;
#define SINGLETON_GET(CLASS,INSTANCE) CLASS* INSTANCE=CLASS::Instance();

#define EXTRACT(FN) bool FN(TextType text,TextSizeType startPos,TextSizeType limitedLength,TextSizeType& extrLength)
#define DUMP(FN) void FN(InfoType dump)

#define INFO_SIZE 9999
#define INFO_SINGLE_SIZE 199
#define EXP_SIZE 9999
#define PRODUCE_REGEX(FN) FN(CodeType start,ExpSizeType length,BasicSpace* basicSpace,ExpSizeType& resLength,InfoType exception,CodeSizeType& excepLoc)
#define PRODUCE_REGEX_A(FN) FN(CodeType start,ExpSizeType length,ExpSizeType& resLength,InfoType exception,CodeSizeType& excepLoc)
//#define PRODUCE_REGEX_B(FN) FN(CodeType start,ExpSizeType& resLength,InfoType exception,CodeSizeType& excepLoc)

namespace etel{
	class BasicSpace;
	class Regex;

	class Factory;

	//BasicSpace
	typedef std::stack<Regex*> RegexPool;
	typedef std::map<char*, Regex*> RegexDict;

	typedef long TextSizeType;
	typedef wchar_t* TextType;
	typedef wchar_t CodeUnitType;
	typedef wchar_t* CodeType;
	typedef long CodeSizeType;
	typedef short ExpSizeType;
	typedef wchar_t InfoType[INFO_SIZE + 1];
	typedef wchar_t InfoSingleType[INFO_SINGLE_SIZE+1];
	typedef wchar_t InfoUnitType;
	typedef short InfoSizeType;
	typedef int EncodeType;
}